<!-- 1、这个组件的钩子全部处理成了属性而不是事件，这里做点修改 -->
<!-- 2、组件自定义程度比较高，先封装成简单的功能 -->
<!--新增部分验证：-->
<!--maxSize: 文件大小限制，单位兆-->
<!--maxWidth: 最大宽度，仅图片-->
<!--maxHeight: 最大高度，仅图片-->
<!--strictEqMax: 严格等于最大宽度和高度，仅图片-->
<!--minWidth: 最大宽度，仅图片-->
<!--minHeight: 最大高度，仅图片-->
<!--extList: 文件后缀限制，数组-->
<template>
  <el-upload
    :action="options['action']"
    :headers="options['headers']"
    :multiple="options['multiple']"
    :data="options['data']"
    :name="options['name']"
    :with-credentials="options['with-credentials']"
    :show-file-list="options['show-file-list']"
    :drag="options['drag']"
    :accept="options['accept']"
    :list-type="options['list-type']"
    :auto-upload="options['auto-upload']"
    :http-request="options['http-request']"
    :disabled="options['disabled']"
    :limit="options['limit']"

    :before-upload="this['_before-upload']"
    :on-preview="this['_on-preview']"
    :on-remove="this['_on-remove']"
    :on-success="this['_on-success']"
    :on-error="this['_on-error']"
    :on-progress="this['_on-progress']"
    :on-change="this['_on-change']"
    :on-exceed="this['_on-exceed']"

    ref="upload"
    :file-list="value"
  >
    <slot name="tip" slot="tip"></slot>
    <slot name="button"></slot>
  </el-upload>
</template>

<script>

	import { Message, MessageBox, Notification } from 'element-ui';

export default {
  props: {
    'options': {
      default: Object,
      required: true
    },
    'value': {
      required: true
    }
  },
  methods: {
    '_before-upload' (file) {
      this.$emit('before-upload', file)
		// 文件大小
		let maxSize = !this.options.maxSize || file.size/1024/1024<=this.options.maxSize;
		  if(!maxSize){
			  Message({message: `文件大小不能超过 ${this.options.maxSize}MB`,type: 'warning',});
			  return false;
		  }
		// 文件后缀
		let extList =!this.options.extList || this.options.extList.some(ext=>file.name.endsWith(`.${ext}`));
		if(!extList){
			Message({message: `文件必须是以下类型：${this.options.extList}`,type: 'warning',});
			return false;
		}
		// 回调暂时不支持promise
		let callback = !this.options['@before-upload'] || this.options['@before-upload'](file);
		if(!callback){
			return false;
		}
		// maxWidth & maxHeight & strictEqMax & minWidth & minHeight
		// 仅图片，其他文件不要设置这四个属性
		if(this.options.maxWidth || this.options.maxHeight || this.options.minWidth || this.options.minHeight){
			let imgSize = new Promise((resolve, reject)=>{
				let {maxWidth, maxHeight, strictEqMax, minWidth, minHeight} = this.options;
				let _URL = window.URL || window.webkitURL;
				let img = new Image();
				img.onload = ()=>{
					// 验证maxWidth和maxHeight
					if((maxWidth && (strictEqMax?img.width !== maxWidth:img.width>maxWidth)) ||
						(maxHeight) && (strictEqMax?img.height !== maxHeight:img.height>maxHeight)){
						Message({message: strictEqMax?
								`上传的图片尺寸必须为 ${maxWidth||'N'}*${maxHeight||'N'}`:
								`上传的图片尺寸必须小于或等于 ${maxWidth||'N'}*${maxHeight||'N'}`,
								type:'warning'})
						reject();
					}
					// 验证minWidth和minHeight
					else if((minWidth && img.width<minWidth) || (minHeight && img.height<minHeight)){
						Message({message: `上传的图片尺寸必须大于或等于${minWidth||'N'}*${minHeight||'N'}`, type: 'warning'})
						reject();
					}else{
						this.options['@check-ok'] && this.options['@check-ok'](file);
						resolve(file);
					}
				}
				img.src = _URL.createObjectURL(file);
			})
			return imgSize;
		}else{
            this.options['@check-ok'] && this.options['@check-ok'](file);
        }
		return true;
    },
    '_on-preview' (file) {
      this.$emit('on-preview', file)
		this.options['@on-preview']&& this.options['@on-preview'](file)
    },
    // * 这个移除要确认下是本地移除还是服务端
    '_on-remove' (file, fileList) {
		if(fileList.length===0 || !fileList.find(item=>item.status!=='success')){
			this.$emit('input', fileList)
		}
      this.$emit('on-remove', file, fileList)
		this.options['@on-remove']&&this.options['@on-remove'](file, fileList)
    },
    // *
    '_on-success' (response, file, fileList) {
    	// 选择多个文件上传时，需要等待所有的文件上传完毕
		// 有个问题，假如选择了2个文件，第一个上传成功，第二个上传失败，不会触发input事件
    	if(fileList.length===0 || !fileList.find(item=>item.status!=='success')){
			this.$emit('input', fileList)
		}
      this.$emit('on-success', response, file, fileList)
		this.options['@on-success'] && this.options['@on-success'](response, file, fileList)
    },
    '_on-error' (err, file, fileList) {
    	// 防止选择多个文件上传时，部分失败带来的bug，如 _on-success 方法中所述，未验证
		if(fileList.length===0 || !fileList.find(item=>item.status!=='success')){
			this.$emit('input', fileList)
		}
      this.$emit('on-error', err, file, fileList)
		this.options['@on-error'] && this.options['@on-error'](err, file, fileList)
    },
    '_on-progress' (event, file, fileList) {
      this.$emit('on-progress', event, file, fileList)
		this.options['@on-progress'] && this.options['@on-progress'](event, file, fileList)
    },
    // 添加、上传成功、失败
    '_on-change' (file, fileList) {
      this.$emit('on-change', file, fileList)
		this.options['@on-change'] && this.options['@on-change'](file, fileList)
    },
    '_on-exceed' (file, fileList) {
      this.$emit('on-exceed', file, fileList)
		Message(({
			message: `最多只能选择 ${this.options.limit} 个文件`,
			type: 'warning',
		}))
		this.options['@on-exceed'] && this.options['@on-exceed'](file, fileList)
    },
    clearFiles () {
      this.$refs['upload'].clearFiles()
    },
    abort () {
      this.$refs['upload'].abort()
    }
  }
}
</script>
